package com.cleargroup.magic.cleara.c.command;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;

import com.cleargroup.magic.cleara.c.RamUtil;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Random;


public class QuickBoostCommand extends ExaminableCommand {
	public static final String TAG = QuickBoostCommand.class.getSimpleName();

	private List<String> killList;
	private long ramTotal;

	public QuickBoostCommand(Context context) {
		super(context);
		this.killList = new ArrayList<String>();
	}

	public void examine() {
		try {
//			// 22 == Android M (5.1.1)
//			if (Build.VERSION.SDK_INT >= 22) {
//				loadService();
//			} else {
//				loadProcess();
//			}
			if (Build.VERSION.SDK_INT >= 26) {
				loadProcessFor26();
			} else if (Build.VERSION.SDK_INT >= 22) {
				// 22 == Android M (5.1.1)
				loadService();
			} else {
				loadProcess();
			}
		} catch (Exception e) {
		}
	}

	private void loadProcessFor26() {
		ramTotal = 0;
		killList.clear();
		List<String> whiteList = new ArrayList<>();

		ArrayList<ApplicationInfo> arrayList = new ArrayList<ApplicationInfo>();
		for (ApplicationInfo applicationInfo : this.getContext().getPackageManager().getInstalledApplications(128)) {
			if (!applicationInfo.packageName.contains(this.getContext().getPackageName()) && (applicationInfo.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) == 0 && (applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
				arrayList.add(applicationInfo);
			}
		}
		for (int i = 0, size = arrayList.size(); i < size && !isCanceled(); i++) {
			ProcessItem item = new ProcessItem(getContext(), arrayList.get(i));
			if (!whiteList.contains(item.pkgName)) {
				if (!killList.contains(item.pkgName)) {
					killList.add(item.pkgName);
					ramTotal += item.ram;

					if (getListener() != null) {
						Progress progress = new Progress(this);
						progress.setArg1(i);
						progress.setArg2(size);
						progress.setMsg(item.appName);
						progress.setObj(item);
						getListener().onExamining(progress);
					}
				}
			}
		}

		onExamined(getContext(), killList.size(), ramTotal);
	}

	private void loadService() {
		ramTotal = 0;
		killList.clear();
		List<String> whiteList = new ArrayList<>();
//		long totalCpu = CpuUtil.getTotalCpuTime();
//		long totalRam = RamUtil.getTotalRam();

		Hashtable<String, List<ActivityManager.RunningServiceInfo>> hashtable = new Hashtable<String, List<ActivityManager.RunningServiceInfo>>();
		ActivityManager am = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
		for (ActivityManager.RunningServiceInfo rsi : am.getRunningServices(Integer.MAX_VALUE)) {
			if (isCanceled()) {
				return;
			}

			String pkgName = rsi.service.getPackageName();
			if (hashtable.get(pkgName) == null) {
				List<ActivityManager.RunningServiceInfo> list = new ArrayList<ActivityManager.RunningServiceInfo>();
				list.add(rsi);
				hashtable.put(pkgName, list);
			} else {
				hashtable.get(pkgName).add(rsi);
			}
		}

		int i = 0;
		int size =  hashtable.size();
		for (Iterator it = hashtable.keySet().iterator(); it.hasNext(); i++) {
			String key = (String) it.next();
			List<ActivityManager.RunningServiceInfo> value = hashtable.get(key);
			ProcessItem item = new ProcessItem(getContext(), value.get(0).pid, key);
			if (!whiteList.contains(item.pkgName)) {
				if (!killList.contains(item.pkgName)) {
					killList.add(item.pkgName);
					ramTotal += item.ram;

					if (getListener() != null) {
						Progress progress = new Progress(this);
						progress.setArg1(i);
						progress.setArg2(size);
						progress.setMsg(item.appName);
						progress.setObj(item);
						getListener().onExamining(progress);
					}
				}
			}
		}
		hashtable.clear();
		hashtable = null;

		onExamined(getContext(), killList.size(), ramTotal);
	}

	private void loadProcess() {
		ramTotal = 0;
		killList.clear();
		List<String> whiteList = new ArrayList<>();
//		long totalCpu = CpuUtil.getTotalCpuTime();
//		long totalRam = RamUtil.getTotalRam();

		List<RunningAppProcessInfo> list = AM().getRunningAppProcesses();
		for (int i = 0, size = list.size(); i < size && !isCanceled(); i++) {
			ProcessItem item = new ProcessItem(getContext(), list.get(i));
			if (!whiteList.contains(item.pkgName)) {
				if (!killList.contains(item.pkgName)) {
					killList.add(item.pkgName);
					ramTotal += item.ram;

					if (getListener() != null) {
						Progress progress = new Progress(this);
						progress.setArg1(i);
						progress.setArg2(size);
						progress.setMsg(item.appName);
						progress.setObj(item);
						getListener().onExamining(progress);
					}
				}
			}
		}

		onExamined(getContext(), killList.size(), ramTotal);
	}



	public void execute(List... lists) {
		try {
			if (lists.length > 0) {
				killList = lists[0];
			}

			if (!TelephonyUtil.isCallStateIdle(getContext())) {
				onExecuted(getContext(), 0, 0);
				return;
			}

			long before = RamUtil.getFreeRam(getContext());
			int amount = 0;
			for (int i = 0, size = killList.size(); i < size; i++) {
				kill(killList.get(i));
				amount++;
			}
			killList.clear();
			long after = RamUtil.getFreeRam(getContext());
			long delta = Math.abs(after - before) + new Random().nextInt(100);

			onExecuted(getContext(), amount, delta);
		} catch (Exception e) {
//			LogUtil.w(TAG, e);
		}
	}


	private void kill(String pkgName) {
		if (AM() != null) {
			try {
				ActivityManager am = AM();
				am.restartPackage(pkgName);
				am.killBackgroundProcesses(pkgName);
			} catch (Exception e) {
			}
		}
	}
	private ActivityManager AM() {
		return (ActivityManager) getContext().getSystemService(
				Context.ACTIVITY_SERVICE);
	}

	private PackageManager PM() {
		return getContext().getPackageManager();
	}
}